/***************************************************************************
 * Kinect Listener
 * -uses OpenNI classes to receive data from Kinect and interpret it
 * -callback methods are invoked when hand points are found/updated and gestures are made
 *                                                                         
 ***************************************************************************/

#ifndef KINECT_LISTENER_H
#define KINECT_LISTENER_H

#include <QTimer>
#include <QThread>
#include "qapplication.h"
#include "devices/KinectHandler.h"
#include <stdio.h>

//OpenNI and NITE headers
#include <XnOpenNI.h>
#include <XnVSessionManager.h>
#include <XnVPushDetector.h>
#include <XnVPointFilter.h>
#include <XnVWaveDetector.h>
#include <XnVSwipeDetector.h>

#include "kbhit.h"
#include "signal_catch.h"

// XML to initialize OpenNI, make sure XML file is located here
#define SAMPLE_XML_PATH "./Sample-Tracking.xml"

//class to allow for tracking and gestures from two hands; mimics two sessions
class XnVSecondaryFilter: public XnVPointFilter {
public:
	XnVSecondaryFilter(): m_nNewPrimary(0) {}

	// Create a local copy of all the hands, and set a primary for the subtree.
	void Update(const XnVMultipleHands& hands);
	void Update(XnVMessage* pMessage);

protected:
	XnUInt32 m_nNewPrimary;
	XnVMultipleHands m_LocalCopy;
};

//listener wrapper around NITE modules; is a separate thread from GUI
class KinectListener: public QThread {
	Q_OBJECT

public:
    KinectListener(KinectHandler *handler);
    ~KinectListener();

	bool checkDeviceConnection();

	bool init();
	void run();
    
public slots:
    void updateKinect();

signals:
	void signalKinectConnected();

private:
	//internal timer to update Kinect data every 15ms
	QTimer *m_timer;

	//OpenNI/NITE objects
	xn::Context *m_ctx;
	xn::HandsGenerator *m_handsGenerator;
	xn::DepthGenerator *m_depthGenerator;
	XnVSessionManager *m_sessionManager;
	XnVWaveDetector *m_waveDetector1, *m_waveDetector2;
	XnVPushDetector *m_pd1, *m_pd2;
	XnVSecondaryFilter *m_secFilter;
};

#endif // KINECT_LISTENER_H
